#if defined(__i386__)
/* Destroy low mappings - they were only for our convenience. */
zap_low_mappings(l2start);
- zap_low_mappings(idle_pg_table_l2);
#endif
update_domain_wallclock_time(d);
return 0;
}
+void free_xen_pagetable(void *v)
+{
+ extern int early_boot;
+
+ BUG_ON(early_boot);
+
+ if ( is_xen_heap_frame(virt_to_page(v)) )
+ free_xenheap_page(v);
+ else
+ free_domheap_page(virt_to_page(v));
+}
+
int map_pages_to_xen(
unsigned long virt,
unsigned long mfn,
return 0;
}
+void destroy_xen_mappings(unsigned long s, unsigned long e)
+{
+ l2_pgentry_t *pl2e;
+ l1_pgentry_t *pl1e;
+ unsigned int i;
+ unsigned long v = s;
+
+ ASSERT((s & ~PAGE_MASK) == 0);
+ ASSERT((e & ~PAGE_MASK) == 0);
+
+ while ( v < e )
+ {
+ pl2e = virt_to_xen_l2e(v);
+
+ if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
+ {
+ v += PAGE_SIZE;
+ continue;
+ }
+
+ if ( l2e_get_flags(*pl2e) & _PAGE_PSE )
+ {
+ if ( (l1_table_offset(v) == 0) &&
+ ((e-v) >= (1UL << L2_PAGETABLE_SHIFT)) )
+ {
+ /* PSE: whole superpage is destroyed. */
+ l2e_write_atomic(pl2e, l2e_empty());
+ v += 1UL << L2_PAGETABLE_SHIFT;
+ }
+ else
+ {
+ /* PSE: shatter the superpage and try again. */
+ pl1e = alloc_xen_pagetable();
+ for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
+ l1e_write(&pl1e[i],
+ l1e_from_pfn(l2e_get_pfn(*pl2e) + i,
+ l2e_get_flags(*pl2e) & ~_PAGE_PSE));
+ l2e_write_atomic(pl2e, l2e_from_pfn(virt_to_mfn(pl1e),
+ __PAGE_HYPERVISOR));
+ }
+ }
+ else
+ {
+ /* Ordinary 4kB mapping. */
+ pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(v);
+ l1e_write_atomic(pl1e, l1e_empty());
+ v += PAGE_SIZE;
+
+ /* If we are done with the L2E, check if it is now empty. */
+ if ( (v != e) && (l1_table_offset(v) != 0) )
+ continue;
+ pl1e = l2e_to_l1e(*pl2e);
+ for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
+ if ( l1e_get_intpte(pl1e[i]) != 0 )
+ break;
+ if ( i == L1_PAGETABLE_ENTRIES )
+ {
+ /* Empty: zap the L2E and free the L1 page. */
+ l2e_write_atomic(pl2e, l2e_empty());
+ free_xen_pagetable(pl1e);
+ }
+ }
+ }
+
+ flush_tlb_all_pge();
+}
+
void __set_fixmap(
enum fixed_addresses idx, unsigned long mfn, unsigned long flags)
{
if ( smp_found_config )
get_smp_config();
+#ifdef CONFIG_X86_64
+ /* Low mappings were only needed for some BIOS table parsing. */
+ zap_low_mappings();
+#endif
+
init_apic_mappings();
init_IRQ();
#ifdef CONFIG_X86_IO_APIC
setup_ioapic_dest();
#endif
-#ifdef CONFIG_X86_64
- zap_low_mappings();
-#endif
#ifndef CONFIG_HOTPLUG_CPU
/*
* Disable executability of the SMP trampoline:
return mfn_to_virt(mfn);
}
-void free_xen_pagetable(void *v)
-{
- free_xenheap_page(v);
-}
-
l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
{
return &idle_pg_table_l2[l2_linear_offset(v)];
__PAGE_HYPERVISOR));
}
-void __init zap_low_mappings(l2_pgentry_t *base)
+void __init zap_low_mappings(l2_pgentry_t *dom0_l2)
{
int i;
- u32 addr;
- for ( i = 0; ; i++ )
- {
- addr = i << L2_PAGETABLE_SHIFT;
- if ( addr >= HYPERVISOR_VIRT_START )
- break;
- if ( l2e_get_paddr(base[i]) != addr )
- continue;
- l2e_write(&base[i], l2e_empty());
- }
+ /* Clear temporary idle mappings from the dom0 initial l2. */
+ for ( i = 0; i < (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT); i++ )
+ if ( l2e_get_intpte(dom0_l2[i]) ==
+ l2e_get_intpte(idle_pg_table_l2[i]) )
+ l2e_write(&dom0_l2[i], l2e_empty());
+
+ /* Now zap mappings in the idle pagetables. */
+ destroy_xen_mappings(0, HYPERVISOR_VIRT_START);
flush_tlb_all_pge();
+
+ /* Replace with mapping of the boot trampoline only. */
+ map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
+ 0x10, __PAGE_HYPERVISOR);
}
void __init subarch_init_memory(void)
return mfn_to_virt(mfn);
}
-void free_xen_pagetable(void *v)
-{
- free_domheap_page(virt_to_page(v));
-}
-
l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
{
l4_pgentry_t *pl4e;
void __init zap_low_mappings(void)
{
+ BUG_ON(num_online_cpus() != 1);
+
+ /* Remove aliased mapping of first 1:1 PML4 entry. */
l4e_write(&idle_pg_table[0], l4e_empty());
- flush_tlb_all_pge();
+ local_flush_tlb_pge();
+
+ /* Replace with mapping of the boot trampoline only. */
+ map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
+ 0x10, __PAGE_HYPERVISOR);
}
void __init subarch_init_memory(void)
-
#ifndef __X86_PAGE_H__
#define __X86_PAGE_H__
unsigned long mfn,
unsigned long nr_mfns,
unsigned long flags);
+void destroy_xen_mappings(unsigned long v, unsigned long e);
#endif /* !__ASSEMBLY__ */